package com.liuweiheng.cloud.timer;


import cn.hutool.core.util.ObjectUtil;
import lombok.extern.slf4j.Slf4j;
import org.quartz.Job;
import org.quartz.JobKey;
import org.quartz.TriggerKey;
import org.quartz.utils.Key;

import java.util.Date;
import java.util.Map;

@Slf4j
public class QuartParamBuilder<T extends QuartParam> {

    /**
     * Trigger name and group
     */
    private TriggerKey triggerKey;
    /**
     * 任务类(class extends Job)类名
     */
    private Class<? extends Job> jobClass;
    /**
     * JobDetail name and group
     */
    private JobKey jobKey;
    /**
     * 任务执行中存储的 Map结构数据
     * 每次任务执行完毕后，会删除任务对象导致垃圾回收，会导致存在对象中的全局变量丢失
     * 因此需要用该 Map 来进行存储
     */
    private Map<String, Object> jobDataMap;

    private Map<String, Object> triggerMap;
    /**
     * 判断是否直接启动任务类
     */
    private Boolean startNow = true;
    /**
     * 启动时间
     */
    private Date startAt;
    /**
     * 停用时间
     */
    private Date endAt;
    /**
     * 循环时间类型（时、分、秒、毫秒...）
     */
    private String intervalType;
    /**
     * 循环时间
     */
    private Integer intervalNum;
    /**
     * 是否永久循环定时任务
     */
    private Boolean repeatForever = true;
    /**
     * 循环次数
     */
    private Integer repeatCount;
    /**
     * Cron格式日期
     */
    private String cronDate;
    /**
     * 是否构建简单Trigger执行器
     * 若不是，则构建CronTrigger执行器的参数
     * 根据是否传入Cron格式日期来决定
     */
    private Boolean buildSimple = true;

    private QuartParamBuilder() {}

    public static QuartParamBuilder newQuartParam(Class<? extends Job> jobClass) {
        QuartParamBuilder quartParamBuilder = new QuartParamBuilder();
        quartParamBuilder.ofType(jobClass);
        return quartParamBuilder;
    }


    public SimpleQuartParam buildSimple() {
        SimpleQuartParam param = new SimpleQuartParam();
        if (ObjectUtil.isNull(triggerKey)) {
            this.triggerKey = new TriggerKey(Key.createUniqueName(null), null);
        }
        if (ObjectUtil.isNull(jobKey)) {
            this.jobKey =new JobKey(Key.createUniqueName(null), null);
        }
        if (ObjectUtil.isNotNull(jobDataMap)) {
            param.setJobDataMap(this.jobDataMap);
        }
        if (ObjectUtil.isNotNull(triggerMap)) {
            param.setTriggerMap(this.triggerMap);
        }

        param.setStartNow(this.startNow);
        if (!startNow) {
            param.setStartAt(this.startAt);
        }
        param.setTriggerKey(triggerKey);
        param.setJobKey(jobKey);
        param.setEndAt(endAt);
        param.setIntervalType(intervalType);
        param.setIntervalNum(intervalNum);
        param.setRepeatForever(repeatForever);
        param.setRepeatCount(repeatCount);
        param.setJobClass(jobClass);

        return param;
    }

    public CronQuartParam buildCron() {
        CronQuartParam param = new CronQuartParam();
        if (ObjectUtil.isNull(triggerKey)) {
            this.triggerKey = new TriggerKey(Key.createUniqueName(null), null);
        }
        if (ObjectUtil.isNull(jobKey)) {
            this.jobKey =new JobKey(Key.createUniqueName(null), null);
        }
        if (ObjectUtil.isNotNull(jobDataMap)) {
            param.setJobDataMap(this.jobDataMap);
        }
        if (ObjectUtil.isNotNull(triggerMap)) {
            param.setTriggerMap(this.triggerMap);
        }
        param.setTriggerKey(triggerKey);
        param.setJobKey(jobKey);
        param.setCronDate(this.cronDate);
        param.setEndTime(this.endAt);
        param.setJobClass(jobClass);

        return param;
    }


    public QuartParamBuilder withTriggerKey(String name) {
        return withTriggerKey(name, null);
    }

    public QuartParamBuilder withTriggerKey(String name, String group) {
        this.triggerKey = new TriggerKey(name, group);
        return this;
    }

    public QuartParamBuilder withJobKey(String name) {
        return withJobKey(name, null);
    }

    public QuartParamBuilder withJobKey(String name, String group) {
        this.jobKey = new JobKey(name, group);
        return this;
    }

    public QuartParamBuilder ofType(Class<? extends Job> jobClass) {
        this.jobClass = jobClass;
        return this;
    }

    public QuartParamBuilder withJobDataMap(Map<String, Object> map) {
        this.jobDataMap = map;
        return this;
    }

    public QuartParamBuilder withTriggerMap(Map<String, Object> map) {
        this.triggerMap = map;
        return this;
    }

    public QuartParamBuilder withStartAt(Date startTime) {
        this.startAt = startTime;
        this.startNow = false;
        return this;
    }

    public QuartParamBuilder withEndAt(Date endTime) {
        this.endAt = endTime;
        return this;
    }

    public QuartParamBuilder withIntervalType(String intervalType) {
        this.intervalType = intervalType;
        return this;
    }

    public QuartParamBuilder withIntervalNum(Integer intervalNum) {
        this.intervalNum = intervalNum;
        return this;
    }

    public QuartParamBuilder withRepeatCount(Integer repeatCount) {
        this.repeatCount = repeatCount;
        this.repeatForever = false;
        return this;
    }

    public QuartParamBuilder withCronDate(String date) {
        this.cronDate = date;
        this.buildSimple = false;
        return this;
    }
}
